﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace PrimitiveEngine.Primitives
{
    public class PELine : PEPrimitive
    {
        public Vector2 Start;
        public Vector2 End;
        public float Width;

        public override int PrimitiveCount { get { return primitiveCount; } }

        internal int primitiveCount = 0;

        internal static Vector2[] texCoords = new Vector2[] { new Vector2(0, 0), new Vector2(1, 0), new Vector2(0, 1), new Vector2(1, 1) };

        internal static Vector3[] tempArray1 = new Vector3[4];
        internal static Vector3[] tempArray2 = new Vector3[4];


        public PELine()
        {
            Type = PEPrimitiveType.Line;
        }

        public PELine(Vector2 start, Vector2 end)
        {
            Type = PEPrimitiveType.Line;
            Start = start;
            End = end;
            Layer = 1f;
            FillColor = Color.White;
            IsFilled = true;
            BorderColor = Color.Black;
            Width = 1.0f;
        }

        public PELine(Vector2 start, Vector2 end, Color color)
        {
            Type = PEPrimitiveType.Line;
            Start = start;
            End = end;
            Layer = 1f;
            FillColor = color;
            IsFilled = true;
            BorderColor = Color.Black;
            Width = 1.0f;
        }

        public PELine(Vector2 start, Vector2 end, float layer, Color color)
        {
            Type = PEPrimitiveType.Line;
            Start = start;
            End = end;
            Layer = layer;
            FillColor = color;
            IsFilled = true;
            BorderColor = Color.Black;
            Width = 1.0f;
        }

        public PELine(Vector2 start, Vector2 end, float width, float layer, Color color)
        {
            Type = PEPrimitiveType.Line;
            Start = start;
            End = end;
            Layer = layer;
            FillColor = color;
            IsFilled = true;
            BorderColor = Color.Black;
            Width = width;
        }
        
        public override bool Intersection(PEPrimitive primitive)
        {
            throw new NotImplementedException();
        }

        public override bool Inside(Microsoft.Xna.Framework.Vector2 point)
        {
            throw new NotImplementedException();
        }

        public override void CreateUV()
        {
            throw new NotImplementedException();
        }

        public override void Draw(ref VertexPositionColorTexture[] vertices, ref int vertexIndex, ref short[] indices, ref int indiceIndex)
        {
            Vector2 normal;
            float w = Width * 0.5f;
            int tempIndex = vertexIndex;
            primitiveCount = 0;

            // get the normal of the line
            normal = Vector2Ext.FindEdgeNormal(Start, End);

            tempArray1[0] = new Vector3(-normal * w + Start, -Layer);
            tempArray1[1] = new Vector3(normal * w + Start, -Layer);
            tempArray1[2] = new Vector3(normal * w + End, -Layer);
            tempArray1[3] = new Vector3(-normal * w + End, -Layer);

            w = Width * 0.5f - BorderWidth;
            Vector2 startNormal = Start - End;
            startNormal.Normalize();

            Vector2 endNormal = End - Start;
            endNormal.Normalize();

            tempArray2[0] = new Vector3(-normal * w + Start - startNormal * BorderWidth, -Layer);
            tempArray2[1] = new Vector3(normal * w + Start - startNormal * BorderWidth, -Layer);
            tempArray2[2] = new Vector3(normal * w + End - endNormal * BorderWidth, -Layer);
            tempArray2[3] = new Vector3(-normal * w + End - endNormal * BorderWidth, -Layer);

            if (IsFilled)
            {
                vertices[vertexIndex].Position = tempArray2[1];
                vertices[vertexIndex].Color = FillColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[0];
                vertexIndex++;
                vertices[vertexIndex].Position = tempArray2[0];
                vertices[vertexIndex].Color = FillColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[1];
                vertexIndex++;
                vertices[vertexIndex].Position = tempArray2[2];
                vertices[vertexIndex].Color = FillColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[2];
                vertexIndex++;
                vertices[vertexIndex].Position = tempArray2[3];
                vertices[vertexIndex].Color = FillColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[3];
                vertexIndex++;

                // create the indices
                indices[indiceIndex + 0] = (short)(tempIndex + 0);
                indices[indiceIndex + 1] = (short)(tempIndex + 2);
                indices[indiceIndex + 2] = (short)(tempIndex + 3);
                indices[indiceIndex + 3] = (short)(tempIndex + 0);
                indices[indiceIndex + 4] = (short)(tempIndex + 3);
                indices[indiceIndex + 5] = (short)(tempIndex + 1);
                indiceIndex += 6;

                primitiveCount += 2;

                tempIndex = vertexIndex;
            }

            if (BorderWidth > 0)
            {
                vertices[vertexIndex].Position = tempArray1[0];
                vertices[vertexIndex].Color = BorderColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[0];
                vertexIndex++;
                vertices[vertexIndex].Position = tempArray1[1];
                vertices[vertexIndex].Color = BorderColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[1];
                vertexIndex++;
                vertices[vertexIndex].Position = tempArray1[2];
                vertices[vertexIndex].Color = BorderColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[2];
                vertexIndex++;
                vertices[vertexIndex].Position = tempArray1[3];
                vertices[vertexIndex].Color = BorderColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[3];
                vertexIndex++;
                vertices[vertexIndex].Position = tempArray2[0];
                vertices[vertexIndex].Color = BorderColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[0];
                vertexIndex++;
                vertices[vertexIndex].Position = tempArray2[1];
                vertices[vertexIndex].Color = BorderColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[1];
                vertexIndex++;
                vertices[vertexIndex].Position = tempArray2[2];
                vertices[vertexIndex].Color = BorderColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[2];
                vertexIndex++;
                vertices[vertexIndex].Position = tempArray2[3];
                vertices[vertexIndex].Color = BorderColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[3];
                vertexIndex++;

                indices[indiceIndex + 0] = (short)(tempIndex + 0);
                indices[indiceIndex + 1] = (short)(tempIndex + 1);
                indices[indiceIndex + 2] = (short)(tempIndex + 5);
                indices[indiceIndex + 3] = (short)(tempIndex + 0);
                indices[indiceIndex + 4] = (short)(tempIndex + 5);
                indices[indiceIndex + 5] = (short)(tempIndex + 4);
                indiceIndex += 6;

                indices[indiceIndex + 0] = (short)(tempIndex + 1);
                indices[indiceIndex + 1] = (short)(tempIndex + 2);
                indices[indiceIndex + 2] = (short)(tempIndex + 5);
                indices[indiceIndex + 3] = (short)(tempIndex + 2);
                indices[indiceIndex + 4] = (short)(tempIndex + 6);
                indices[indiceIndex + 5] = (short)(tempIndex + 5);
                indiceIndex += 6;

                indices[indiceIndex + 0] = (short)(tempIndex + 2);
                indices[indiceIndex + 1] = (short)(tempIndex + 7);
                indices[indiceIndex + 2] = (short)(tempIndex + 3);
                indices[indiceIndex + 3] = (short)(tempIndex + 2);
                indices[indiceIndex + 4] = (short)(tempIndex + 6);
                indices[indiceIndex + 5] = (short)(tempIndex + 7);
                indiceIndex += 6;

                indices[indiceIndex + 0] = (short)(tempIndex + 7);
                indices[indiceIndex + 1] = (short)(tempIndex + 3);
                indices[indiceIndex + 2] = (short)(tempIndex + 0);
                indices[indiceIndex + 3] = (short)(tempIndex + 0);
                indices[indiceIndex + 4] = (short)(tempIndex + 4);
                indices[indiceIndex + 5] = (short)(tempIndex + 7);
                indiceIndex += 6;

                primitiveCount += 8;
            }
        }
    }
}
